package com.guodi.model.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.guodi.common.constant.StatusCode;
import com.guodi.common.utils.AjaxResult;
import com.guodi.common.utils.UuidUtil;
import com.guodi.core.boot.ctrl.BaseController;
import com.guodi.model.entity.*;
import com.guodi.model.service.*;
import com.guodi.model.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import javax.annotation.Resource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @描述：指标上报值表控制类
 * @作者: 彭辉
 * @日期: 2020-06-05
 */
@RestController
@RequestMapping("/IdtReportValue")
@Api(value = "API - IdtReportValueController", description = "指标上报值表")
public class IdtReportValueController extends BaseController {

    @Resource
    private IIdtReportValueService idtReportValueService;

    @Resource
    private IIdtIndicatorsService iIdtIndicatorsService;

    @Resource
    private IIdtIndicatorsTypeService iIdtIndicatorsTypeService;

    @Resource
    private IIdtIndicatorsDirService iIdtIndicatorsDirService;

    @Resource
    private IIdtYearRelevanceService iIdtYearRelevanceService;

    @Resource
    private IIdtTargetValueService iIdtTargetValueService;


    /**
     * @描述: 获取指标上报的所有年份值列表
     * @入参: idtTypeCode 指标体系编码
     * @入参: divisionCode 行政区划编码
     * @出参: 指标上报的所有年份值列表
     * @作者: 陈宏成
     * @日期: 2021-02-05
     **/
    @PostMapping("/listIdtReportYear")
    @ApiOperation(value = " 获取指标上报的所有年份值列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "idtTypeCode", value = "指标体系编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "行政区划编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "idtTypeId", value = "指标体系ID", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult listIdtReportYear(String idtTypeCode, String divisionCode, String idtTypeId){
        String deptId = this.getUser().getDeptId();
        List<Integer> yearList = idtReportValueService.listIdtReportYear(idtTypeCode, divisionCode, deptId, idtTypeId);
        return new AjaxResult(yearList);
    }

    /**
     * @描述: 根据实体属性分页查询
     * @入参:
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/listByKeyWord")
    @ApiOperation(value = " 根据关键字进行查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "current", value = "当前页码", required = true, dataType = "long", paramType = "query", example = "1"),
            @ApiImplicitParam(name = "size", value = "每页显示数量", required = true, dataType = "long", paramType = "query", example = "10"),
            @ApiImplicitParam(name = "keyWord", value = "关键字搜索", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "year", value = "年份搜索", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "sort", value = "排序字段", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "sortWay", value = "排序方式", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "行政区划代码", dataType = "string", paramType = "query")
    })
    public AjaxResult listByKeyWord(@ApiIgnore Page page, String keyWord, String year, String sort, String sortWay, String divisionCode){
        String deptId = this.getUser().getDeptId();
        if (StringUtils.isBlank(deptId)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "该用户所属部门不存在");
        }
        String orgId =deptId;
        HashMap map = new HashMap();
        Long start = (page.getCurrent()-1)*page.getSize();

        Integer yearNum = null;
        if (StringUtils.isNotBlank(year)) {
            yearNum = Integer.valueOf(year);
        }
        List<IdtReportValue> idtReportValueList =idtReportValueService.listByKeyWord(keyWord, yearNum, page.getSize(),start,sort,sortWay,divisionCode,orgId);
        //设置行政区划名称
        for (int i = 0; i <idtReportValueList.size() ; i++) {
            String divisionName = idtReportValueService.getNameByDivisionCode(idtReportValueList.get(i).getDivisionCode());
            idtReportValueList.get(i).setDivisionName(divisionName);
        }
        Integer selectCount = idtReportValueService.listByKeyWordAndCodeCount(keyWord,yearNum,divisionCode,orgId);
        map.put("records",idtReportValueList);
        map.put("total",selectCount);
        map.put("size",page.getSize());
        map.put("current",page.getCurrent());
        map.put("searchCount",true);
        map.put("pages",selectCount%page.getSize() == 0 ?selectCount/page.getSize() : selectCount/page.getSize() +1);
        return new AjaxResult(map);
    }

    /**
     * @描述: 根据主键查询
     * @入参:
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/findById")
    @ApiOperation(value = "根据主键查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = true,
                    dataType = "string", paramType = "query")
    })
    public AjaxResult findById(String id) {
        if(StringUtils.isBlank(id)){
            return new AjaxResult(StatusCode.ERROR_CODE_40005,"id不能为空");
        }
        IdtReportValue idtReportValue = idtReportValueService.getById(id);
        return new AjaxResult(idtReportValue);
    }

    /**
     * @描述: 新增
     * @入参:
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/save")
    @ApiOperation(value = "新增")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "year", value = "年份", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "行政区划编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "value", value = "上报值", required = true,dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "is_standard", value = "是否符合达标率（上报值对比目标值 ：1-达标，0-未达标）", required = false,dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "is_unify", value = "是否符合统一率（上报值等于监测值：1-统一，0-未统一）", required = false,dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "warnStatus", value = "预警状态", required = false,dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "sumStatus", value = "汇总状态（complete：完成汇总，part：汇总部分、auto：自主上报）", required = false,dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "sumExplain", value = "汇总说明", required = false,dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "indicatorsExplain", value = "指标说明", required = false,dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "indicatorsId", value = "监测值", required = true,dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "explain", value = "指标说明", required = false,dataType = "string", paramType = "query")
    })
    public AjaxResult save(IdtReportValue idtReportValue){
        String deptId = this.getUser().getDeptId();
        if (StringUtils.isBlank(deptId)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "改用户所属部门不存在");
        }
        //相同指标不允许添加相同的监测年份
        LambdaQueryWrapper<IdtReportValue> queryWrapper = new QueryWrapper().lambda();
        queryWrapper.eq(IdtReportValue::getIndicatorsId,idtReportValue.getIndicatorsId());
        queryWrapper.eq(IdtReportValue::getYear,idtReportValue.getYear());
        queryWrapper.eq(IdtReportValue::getDivisionCode,idtReportValue.getDivisionCode());
        List<IdtReportValue> list = idtReportValueService.list(queryWrapper);
        if(list.size() >0){
            return new AjaxResult(StatusCode.ERROR_CODE_40005,"该指标所处年份、行政区划上报值已存在");
        }
        prepareData(idtReportValue, true);
        // 处理行政区划代码位数问题
        // 注：2021-04-28 11:19:00去除行政区划代码补充00
//        idtReportValue.setDivisionCode(idtReportValue.getDivisionCode().length() == 2 ? idtReportValue.getDivisionCode() + "0000" : idtReportValue.getDivisionCode().length() == 4 ? idtReportValue.getDivisionCode() + "00" : idtReportValue.getDivisionCode());
        idtReportValue.setId(UuidUtil.get32UUID());
        String divisionName = idtReportValueService.getNameByDivisionCode(idtReportValue.getDivisionCode());
        idtReportValue.setDivisionName(divisionName);
        //关联指标信息
        IdtIndicators idtIndicators = iIdtIndicatorsService.getById(idtReportValue.getIndicatorsId());
        if(idtIndicators != null){
            idtReportValue.setIdtCode(idtIndicators.getCode());
            idtReportValue.setIdtName(idtIndicators.getName());
            idtReportValue.setIdtUnit(idtIndicators.getUnit());
        }
        idtReportValue.setId(UuidUtil.get32UUID());
        idtReportValue.setOrgId(deptId);
        //判断是否统一
        Integer unify = idtReportValueService.isUnify(idtReportValue.getIndicatorsId(), idtReportValue.getYear() + "", idtReportValue.getDivisionCode(), idtReportValue.getValue());
        idtReportValue.setIsUnify(unify);
        //判断是否达标
        Integer standard = idtReportValueService.isStandard(idtReportValue.getIndicatorsId(), idtReportValue.getYear() + "", idtReportValue.getDivisionCode(), idtReportValue.getValue());
        idtReportValue.setIsStandard(standard);
        idtReportValueService.save(idtReportValue);
        // 更新指标表中的更新状态
        iIdtIndicatorsService.updateReportStatus(idtReportValue.getIndicatorsId());
        return new AjaxResult(idtReportValue);
    }

    /**
     * @描述: 修改
     * @入参:
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/update")
    @ApiOperation(value = "修改")
    public AjaxResult update(IdtReportValue idtReportValue) {
        String deptId = this.getUser().getDeptId();
        if (StringUtils.isBlank(deptId)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "改用户所属部门不存在");
        }
        //相同指标不允许添加相同的监测年份listByKeyWord
        LambdaQueryWrapper<IdtReportValue> queryWrapper = new QueryWrapper().lambda();
        queryWrapper.eq(IdtReportValue::getIndicatorsId,idtReportValue.getIndicatorsId());
        queryWrapper.eq(IdtReportValue::getYear,idtReportValue.getYear());
        queryWrapper.eq(IdtReportValue::getDivisionCode,idtReportValue.getDivisionCode());
        queryWrapper.ne(IdtReportValue::getId,idtReportValue.getId());
        List<IdtReportValue> list = idtReportValueService.list(queryWrapper);
        if(list.size() >0){
            return new AjaxResult(StatusCode.ERROR_CODE_40005,"该指标所处年份、行政区划上报值已存在");
        }
        prepareData(idtReportValue, false);
        idtReportValue.setOrgId(deptId);
        //判断是否统一
        Integer unify = idtReportValueService.isUnify(idtReportValue.getIndicatorsId(), idtReportValue.getYear() + "", idtReportValue.getDivisionCode(), idtReportValue.getValue());
        idtReportValue.setIsUnify(unify);
        //判断是否达标
        Integer standard = idtReportValueService.isStandard(idtReportValue.getIndicatorsId(), idtReportValue.getYear() + "", idtReportValue.getDivisionCode(), idtReportValue.getValue());
        idtReportValue.setIsStandard(standard);
        idtReportValueService.updateById(idtReportValue);
        // 更新指标表中的更新状态
        iIdtIndicatorsService.updateReportStatus(idtReportValue.getIndicatorsId());
        return new AjaxResult(idtReportValue);
    }

    /**
     * @描述: 根据主键删除
     * @入参: id
     * @出参:
     * @作者: 彭辉
     * @日期: 2020-06-05
     **/
    @PostMapping("/delete")
    @ApiOperation(value = "根据主键删除")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = true,
                    dataType = "string", paramType = "query")
    })
    public AjaxResult delete(String id){
        // 更新指标状态
        IdtReportValue idtReportValue = idtReportValueService.getById(id);
        idtReportValueService.removeById(id);
        iIdtIndicatorsService.updateReportStatus(idtReportValue.getIndicatorsId());
        return new AjaxResult();
    }

    /**
     * @描述:删除多条记录
     * @入参:
     * @出参:
     * @作者: 戴伙进
     * @日期: 2020/6/15 16:55
     **/
    @PostMapping("/deleteByIds")
    @ApiOperation(value = "根据多个id删除,多个id用,隔开")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "ID", required = true,
                    dataType = "string", paramType = "query")
    })
    public AjaxResult deleteByIds(String ids){
        String[] idsAry = ids.split(",");
        List<String> idList = Arrays.asList(idsAry);
        List<IdtReportValue> reportValues = (List<IdtReportValue>)idtReportValueService.listByIds(idList);
        idtReportValueService.removeByIds(idList);
        // 更新指标状态
        List<String> stringList = reportValues.stream().map(x -> x.getIndicatorsId()).collect(Collectors.toList());
        iIdtIndicatorsService.updateReportStatus(String.join(",", stringList));
        return new AjaxResult();
    }

    /**
     * @描述:判断重复数据
     * @入参:
     * @出参:
     * @作者: 郑文彬
     * @日期: 2020/8/28 15:11
     **/
    @PostMapping("/isExistsReport")
    @ApiOperation(value = "判断重复数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "isCheck", value = "是否为指标填报(默认否)", required = false, dataType = "Boolean", paramType = "query"),
            @ApiImplicitParam(name = "code", value = "指标体系编码，isCheck为true时必填", required = false, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "particularYear", value = "指标体系年份", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "行政区划代码", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult isExistsReport(MultipartFile multipartFile, String code, Boolean isCheck, String orgId, String particularYear, String divisionCode) throws Exception {
        String deptId = this.getUser().getDeptId();
        if (StringUtils.isBlank(deptId)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "该用户所属部门不存在");
        }
        if (multipartFile.isEmpty()) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "导入文件不能为空！");
        }
        // 根据上传MultipartFile对象获取excel数据集
        List<List<String>> excelList = ExcelUtil.getExcelData(multipartFile);
        if (excelList == null || excelList.size() <= 1) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "导入文件数据为空！");
        }
        // 去除数据的前后空格
        excelList.stream().forEach(rowList->{
            for(int i = 0; i < rowList.size(); i++) {
                if(rowList.get(i) == null){
                    rowList.set(i,"");
                }else{
                    rowList.set(i,rowList.get(i).trim());
                }
            }
            // 去除指标编码的小数点
            int idtCodeIndex = 0;
            if (rowList.get(idtCodeIndex).contains(".")){
                rowList.set(idtCodeIndex, rowList.get(idtCodeIndex).substring(0, rowList.get(idtCodeIndex).indexOf(".") ));
            }
            // 去除行政区划编码的小数点
            int divisionCodeIndex = 4;
            if (rowList.get(divisionCodeIndex).contains(".")){
                rowList.set(divisionCodeIndex, rowList.get(divisionCodeIndex).substring(0, rowList.get(divisionCodeIndex).indexOf(".") ));
            }
            // 去除年份的小数点
            int yearIndex = 5;
            if (rowList.get(yearIndex).contains(".")){
                rowList.set(yearIndex, rowList.get(yearIndex).substring(0, rowList.get(yearIndex).indexOf(".") ));
            }
        });
        // 查询指标填报中指标数据
        List<String> indicatorsIds = new ArrayList<>();
        if(null != isCheck && isCheck){
            // 暂时写死
            IdtIndicatorsType one = iIdtIndicatorsTypeService.findByCode(code, particularYear, divisionCode);
            if(null != one){
                List<ApiIdtIndicatorsDir> treeList = iIdtIndicatorsDirService.listDirByCode(one.getId(), null,null);
                indicatorsIds = treeList.stream().filter(x -> x.getType()==2).map(x -> x.getIndicatorsId()).collect(Collectors.toList());
            }
        }
        // 存储新增、更新指标集合
        List<IdtReportValue> repeatingData = new ArrayList<>();
        for (int i = 1; i < excelList.size(); i++) {
            List<String> dataList = excelList.get(i);
            String idtCode = dataList.get(0);
            LambdaQueryWrapper<IdtIndicators> queryWrapper = new QueryWrapper().lambda();
            queryWrapper.eq(IdtIndicators::getCode,idtCode);
            IdtIndicators idtIndicators = iIdtIndicatorsService.getOne(queryWrapper);
            IdtReportValue idtReportValue = new IdtReportValue();
            String year = dataList.get(5).indexOf(".") >=0 ? dataList.get(5).substring(0,dataList.get(5).indexOf(".")) : dataList.get(5);
            idtReportValue.setYear(Integer.parseInt(year));
            if(StringUtils.isNotBlank(dataList.get(4))){
                //可能读成数字了，带小数，去掉小数
                if(dataList.get(4).indexOf(".") != -1){
                    String[] str =  dataList.get(4).split("\\.");
                    idtReportValue.setDivisionCode(str[0]);
                }else{
                    idtReportValue.setDivisionCode(dataList.get(4));
                }
            }
            idtReportValue.setIdtCode(idtCode);
            idtReportValue.setValue(dataList.get(6));
            idtReportValue.setId(UuidUtil.get32UUID());
            idtReportValue.setOrgId(deptId);
            idtReportValue.setDivisionName(dataList.get(3));
            if(idtIndicators != null){
                //判断是否存在相同指标id与行政区划编码与相同年份
                LambdaQueryWrapper<IdtReportValue> queryWrapper1 = new QueryWrapper().lambda();
                queryWrapper1.eq(IdtReportValue::getYear,idtReportValue.getYear());
                queryWrapper1.eq(IdtReportValue::getDivisionCode,idtReportValue.getDivisionCode());
                queryWrapper1.eq(IdtReportValue::getIndicatorsId,idtIndicators.getId());
                List<IdtReportValue> sourceIdtReportValueList = idtReportValueService.list(queryWrapper1);
                if(null != isCheck && isCheck){
                    if(indicatorsIds.contains(idtIndicators.getId())){
                        if (sourceIdtReportValueList.size() > 0) {
                            repeatingData.add(idtReportValue);
                        }
                    }
                }else {
                    if (sourceIdtReportValueList.size() > 0) {
                        repeatingData.add(idtReportValue);
                    }
                }
            }
        }
        String resultCodes = "";
        for (IdtReportValue obj : repeatingData) {
            if (!resultCodes.contains(obj.getIdtCode())) {
                resultCodes += StringUtils.isBlank(resultCodes) ? obj.getIdtCode() : "," + obj.getIdtCode();
            }
        }
        return new AjaxResult(resultCodes);
    }

    /**
     * @描述:导入Excel
     * @入参:
     * @出参:
     * @作者: 戴伙进
     * @日期: 2020/6/15 19:03
     **/
    @PostMapping("/importExcel")
    @ApiOperation(value = "导入Excel")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "isUpdate", value = "当同一指标同一地区同一更新周期已经有记录时，是否更新已存在记录，true-更新记录，false-跳过记录（默认false）", required = false, dataType = "Boolean", paramType = "query"),
            @ApiImplicitParam(name = "isCheck", value = "是否为指标填报(默认否)", required = false, dataType = "Boolean", paramType = "query"),
            @ApiImplicitParam(name = "code", value = "指标体系编码，isCheck为true时必填", required = false, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "particularYear", value = "指标体系年份", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "行政区划代码", dataType = "string", paramType = "query")
    })
    public AjaxResult importExcel(MultipartFile multipartFile, Boolean isUpdate, Boolean isCheck, String code, String orgId, String particularYear, String divisionCode) {
        String deptId = this.getUser().getDeptId();
        if (StringUtils.isBlank(deptId)) {
            return new AjaxResult(StatusCode.ERROR_CODE_40005, "改用户所属部门不存在");
        }
        if (multipartFile.isEmpty()) {
            new AjaxResult(StatusCode.ERROR_CODE_40005, "导入文件不能为空！");
        }
        // 根据上传MultipartFile对象获取excel数据集
        List<List<String>> excelList = ExcelUtil.getExcelData(multipartFile);
        if (excelList == null || excelList.size() <= 1) {
            new AjaxResult(StatusCode.ERROR_CODE_40005, "导入文件数据为空！");
        }
        // 去除数据的前后空格
        excelList.stream().forEach(rowList->{
            for(int i = 0; i < rowList.size(); i++) {
                if(rowList.get(i) == null){
                    rowList.set(i,"");
                }else{
                    rowList.set(i,rowList.get(i).trim());
                }
            }
            // 去除指标编码的小数点
            int idtCodeIndex = 0;
            if (rowList.get(idtCodeIndex).contains(".")){
                rowList.set(idtCodeIndex, rowList.get(idtCodeIndex).substring(0, rowList.get(idtCodeIndex).indexOf(".") ));
            }
            // 去除行政区划编码的小数点
            int divisionCodeIndex = 4;
            if (rowList.get(divisionCodeIndex).contains(".")){
                rowList.set(divisionCodeIndex, rowList.get(divisionCodeIndex).substring(0, rowList.get(divisionCodeIndex).indexOf(".") ));
            }
            // 去除年份的小数点
            int yearIndex = 5;
            if (rowList.get(yearIndex).contains(".")){
                rowList.set(yearIndex, rowList.get(yearIndex).substring(0, rowList.get(yearIndex).indexOf(".") ));
            }
        });
        List<String> indicatorsIds = new ArrayList<>();
        if(null != isCheck && isCheck){
            // 暂时写死
            IdtIndicatorsType one = iIdtIndicatorsTypeService.findByCode(code, particularYear, divisionCode);
            if(null != one){
                List<ApiIdtIndicatorsDir> treeList = iIdtIndicatorsDirService.listDirByCode(one.getId(), null,null);
                indicatorsIds = treeList.stream().filter(x -> x.getType()==2).map(x -> x.getIndicatorsId()).collect(Collectors.toList());
            }
        }
        // 存储新增、更新指标集合
        String indicatorsId = "";
        List<IdtReportValue> saveUpdateList = new ArrayList<>();
        for (int i = 1; i < excelList.size(); i++) {
            List<String> dataList = excelList.get(i);
            String idtCode = dataList.get(0);
            LambdaQueryWrapper<IdtIndicators> queryWrapper = new QueryWrapper().lambda();
            queryWrapper.eq(IdtIndicators::getCode,idtCode);
            IdtIndicators idtIndicators = iIdtIndicatorsService.getOne(queryWrapper);
            IdtReportValue idtReportValue = new IdtReportValue();
            String year = dataList.get(5).indexOf(".") >=0 ? dataList.get(5).substring(0,dataList.get(5).indexOf(".")) : dataList.get(5);
            idtReportValue.setYear(Integer.parseInt(year));
            if(StringUtils.isNotBlank(dataList.get(4))){
                //可能读成数字了，带小数，去掉小数
                if(dataList.get(4).indexOf(".") != -1){
                    String[] str =  dataList.get(4).split("\\.");
                    idtReportValue.setDivisionCode(str[0]);
                }else{
                    idtReportValue.setDivisionCode(dataList.get(4));
                }
            }
            idtReportValue.setValue(dataList.get(6));
            // 做非空及数字校验
            if(StringUtils.isNotBlank(dataList.get(6))){
                Boolean isNum = ConvertUtil.isNumeric(dataList.get(6));
                if (!isNum) {
                    return new AjaxResult(StatusCode.ERROR_CODE_40005, "第"+(i+1)+"行上报值不正确，请检查");
                }
            }
            idtReportValue.setExplain(dataList.get(7));
            idtReportValue.setId(UuidUtil.get32UUID());
            idtReportValue.setOrgId(deptId);
            idtReportValue.setDivisionName(dataList.get(3));
            if(idtIndicators != null){
                //判断是否存在相同指标id与行政区划编码与相同年份
                LambdaQueryWrapper<IdtReportValue> queryWrapper1 = new QueryWrapper().lambda();
                queryWrapper1.eq(IdtReportValue::getYear,idtReportValue.getYear());
                queryWrapper1.eq(IdtReportValue::getDivisionCode,idtReportValue.getDivisionCode());
                queryWrapper1.eq(IdtReportValue::getIndicatorsId,idtIndicators.getId());
                List<IdtReportValue> sourceIdtReportValueList = idtReportValueService.list(queryWrapper1);
                if(sourceIdtReportValueList.size() >0){
                    if(isUpdate != null && isUpdate){
                        IdtReportValue reportValue = sourceIdtReportValueList.get(0);
                        reportValue.setValue(idtReportValue.getValue());
                        reportValue.setExplain(idtReportValue.getExplain());
                        idtReportValue = reportValue;
                    }else{
                        continue;
                    }
                }
                idtReportValue.setIndicatorsId(idtIndicators.getId());
                idtReportValue.setIdtCode(idtIndicators.getCode());
                idtReportValue.setIdtName(idtIndicators.getName());
                idtReportValue.setIdtUnit(idtIndicators.getUnit());
                prepareData(idtReportValue,true);
                //判断是否统一
                Integer unify = idtReportValueService.isUnify(idtReportValue.getIndicatorsId(), idtReportValue.getYear() + "", idtReportValue.getDivisionCode(), idtReportValue.getValue());
                idtReportValue.setIsUnify(unify);
                //判断是否达标
                Integer standard = idtReportValueService.isStandard(idtReportValue.getIndicatorsId(), idtReportValue.getYear() + "", idtReportValue.getDivisionCode(), idtReportValue.getValue());
                idtReportValue.setIsStandard(standard);
                if(null != isCheck && isCheck){
                    if(indicatorsIds.contains(idtIndicators.getId())){
                        // 过滤掉excel表里面【指标id、行政区划、年份】相同的记录
                        IdtReportValue temp = idtReportValue;
                        saveUpdateList = saveUpdateList.stream().filter(rv -> {
                            return !(Objects.equals(rv.getIndicatorsId(), temp.getIndicatorsId())
                                    && Objects.equals(rv.getYear(), temp.getYear())
                                    && Objects.equals(rv.getDivisionCode(), temp.getDivisionCode()));
                        }).collect(Collectors.toList());
                        saveUpdateList.add(idtReportValue);
                    }
                }else {
                    // 过滤掉excel表里面【指标id、行政区划、年份】相同的记录
                    IdtReportValue temp = idtReportValue;
                    saveUpdateList = saveUpdateList.stream().filter(rv -> {
                        return !(Objects.equals(rv.getIndicatorsId(), temp.getIndicatorsId())
                                && Objects.equals(rv.getYear(), temp.getYear())
                                && Objects.equals(rv.getDivisionCode(), temp.getDivisionCode()));
                    }).collect(Collectors.toList());
                    saveUpdateList.add(idtReportValue);
                }
                // 存储需要更新的指标
                indicatorsId += idtIndicators.getId();
                indicatorsId += ",";
            }
        }
        if (saveUpdateList.size() > 0) {
            // 批量保存更新
            idtReportValueService.saveOrUpdateBatch(saveUpdateList);
            // 更新指标表中的更新状态
            iIdtIndicatorsService.updateReportStatus(indicatorsId.substring(0, indicatorsId.length() - 1));
        }
        return new AjaxResult(saveUpdateList);
    }

    @PostMapping("/updateUnifyAndStandard")
    @ApiOperation(value = "更新统一及达标字段")
    public AjaxResult updateUnifyAndStandard() throws Exception{
        List<IdtReportValue> reportValueList = idtReportValueService.list();
        for (IdtReportValue idtReportValue : reportValueList) {
            //判断是否统一
            Integer unify = idtReportValueService.isUnify(idtReportValue.getIndicatorsId(), idtReportValue.getYear() + "", idtReportValue.getDivisionCode(), idtReportValue.getValue());
            idtReportValue.setIsUnify(unify);
            //判断是否达标
            Integer standard = idtReportValueService.isStandard(idtReportValue.getIndicatorsId(), idtReportValue.getYear() + "", idtReportValue.getDivisionCode(), idtReportValue.getValue());
            idtReportValue.setIsStandard(standard);
        }
        if (reportValueList.size() > 0) {
            // 批量保存更新
            idtReportValueService.saveOrUpdateBatch(reportValueList);
        }
        return new AjaxResult("更新成功！");
    }

    /**
    * @描述: 导入Json文件
    * @入参:
    * @出参:
    * @作者: 代鹏刚
    * @日期: 2020/11/5 15:20
    **/
    @PostMapping("/exportJson")
    @ApiOperation(value = "导入Json文件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "指标体系编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "orgId", value = "机构id(65fc1451aa4640c795b971ae9199456c)", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "particularYear", value = "指标体系年份", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "行政区划代码", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult exportJson(MultipartFile multipartFile, String code, String orgId, String particularYear, String divisionCode) throws Exception{
        Reader reader = new InputStreamReader(multipartFile.getInputStream(),"utf-8");
        int ch = 0;
        StringBuffer sb = new StringBuffer();
        while ((ch = reader.read()) != -1) {
            sb.append((char) ch);
        }
        reader.close();
        String jsonStr = sb.toString();
        List<IdtReportValue> list = JSONObject.parseArray(jsonStr, IdtReportValue.class);
        List<IdtReportValue> addIdtTargetValueList = new ArrayList<>();
        List<IdtReportValue> updateIdtTargetValueList =  new ArrayList<>();
        if(null == list || list.size() == 0){
            return new AjaxResult(StatusCode.ERROR_CODE_40005,"参数格式错误，请检查");
        }
        List<String> indicatorsIds = new ArrayList<>();
        // 数据筛选 只针对于现状评估的指标数据
        IdtIndicatorsType one = iIdtIndicatorsTypeService.findByCode(code, particularYear, divisionCode);
        if(null != one){
            List<ApiIdtIndicatorsDir> treeList = iIdtIndicatorsDirService.listDirByCode(one.getId(), orgId,null);
            indicatorsIds = treeList.stream().filter(x -> x.getType()==2).map(x -> x.getIndicatorsId()).collect(Collectors.toList());
        }
        for (IdtReportValue idtReportValue: list) {
            LambdaQueryWrapper<IdtReportValue> queryWrapper = new QueryWrapper().lambda();
            queryWrapper.eq(IdtReportValue::getIndicatorsId,idtReportValue.getIndicatorsId());
            queryWrapper.eq(IdtReportValue::getYear,idtReportValue.getYear());
            queryWrapper.eq(IdtReportValue::getDivisionCode,idtReportValue.getDivisionCode());
            List<IdtReportValue> IdtReportValues = idtReportValueService.list(queryWrapper);
            if(indicatorsIds.contains(idtReportValue.getIndicatorsId())){
                if(IdtReportValues.size() >0){
                    IdtReportValue idtTargetValue1 = IdtReportValues.get(0);
                    idtTargetValue1.setValue(idtReportValue.getValue());
                    prepareData(idtTargetValue1,false);
                    //判断是否统一
                    Integer unify = idtReportValueService.isUnify(idtTargetValue1.getIndicatorsId(), idtTargetValue1.getYear() + "", idtTargetValue1.getDivisionCode(), idtTargetValue1.getValue());
                    idtTargetValue1.setIsUnify(unify);
                    //判断是否达标
                    Integer standard = idtReportValueService.isStandard(idtTargetValue1.getIndicatorsId(), idtTargetValue1.getYear() + "", idtTargetValue1.getDivisionCode(), idtTargetValue1.getValue());
                    idtTargetValue1.setIsStandard(standard);
                    updateIdtTargetValueList.add(idtTargetValue1);
                }else {
                    idtReportValue.setId(UuidUtil.get32UUID());
                    prepareData(idtReportValue,true);
                    //判断是否统一
                    Integer unify = idtReportValueService.isUnify(idtReportValue.getIndicatorsId(), idtReportValue.getYear() + "", idtReportValue.getDivisionCode(), idtReportValue.getValue());
                    idtReportValue.setIsUnify(unify);
                    //判断是否达标
                    Integer standard = idtReportValueService.isStandard(idtReportValue.getIndicatorsId(), idtReportValue.getYear() + "", idtReportValue.getDivisionCode(), idtReportValue.getValue());
                    idtReportValue.setIsStandard(standard);
                    addIdtTargetValueList.add(idtReportValue);
                }
            }
        }
        if(addIdtTargetValueList.size() > 0){
            idtReportValueService.saveBatch(addIdtTargetValueList);
        }
        if(updateIdtTargetValueList.size() > 0){
            idtReportValueService.updateBatchById(updateIdtTargetValueList);
        }
        return new AjaxResult();
    }

    /**
     * @描述:导出Excel
     * @入参:
     * @出参:
     * @作者: 戴伙进
     * @日期: 2020/6/18 10:20
     **/
    @PostMapping("/exportExcel")
    @ApiOperation(value = "导出指标Excel")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "exportType", value = "导出类型,传入all默认导出全部,否则根据,分隔删除", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "ids", value = "导出指标id集合", required = false, dataType = "string", paramType = "query")
    })
    public void exportExcel(String exportType, String ids) {
        String deptId = this.getUser().getDeptId();
        if (StringUtils.isBlank(deptId)) {
            return;
        }
        String orgId =deptId;
        List<IdtReportValue> list ;
        //查询指标信息子项信息
        List<IdtIndicators> idtIndicatorsList;
        List<String> stringIdList = new ArrayList<>();
        if ("all".equals(exportType)) {
            // 导出所有指标
            LambdaQueryWrapper<IdtReportValue> queryWrapper = new QueryWrapper().lambda();
            // 因为查看时，没有和机构挂钩，故导出时导出所有。 2020-12-31 汤厚韬
            // queryWrapper.eq(IdtReportValue::getOrgId,orgId);
            list = idtReportValueService.list(queryWrapper);
        } else {
            List<String> idsList = Arrays.asList(ids.split(","));
            // 导出选中指标
            list = (List<IdtReportValue>) idtReportValueService.listByIds(idsList);
        }
        for (int z = 0; z < list.size(); z++) {
            stringIdList.add(list.get(z).getIndicatorsId());
        }
        //指标子项信息
        idtIndicatorsList = (List<IdtIndicators>) iIdtIndicatorsService.list();
        //赋值指标相关子项信息
        for (int i = 0; i <list.size() ; i++) {
            for (int j = 0; j < idtIndicatorsList.size(); j++) {
                if (list.get(i).getIndicatorsId().equals(idtIndicatorsList.get(j).getId())) {
                    IdtIndicators idtIndicators = idtIndicatorsList.get(j);
                    list.get(i).setIdtUnit(idtIndicators.getUnit());
                    list.get(i).setIdtName(idtIndicators.getName());
                    list.get(i).setIdtCode(idtIndicators.getCode());
                    String divisionName = idtReportValueService.getNameByDivisionCode(list.get(i).getDivisionCode());
                    list.get(i).setDivisionName(divisionName);
                }
            }
        }
        List<Object[]> dataList = new ArrayList<Object[]>();
        for (int i = 0; i < list.size(); i++) {
            IdtReportValue idtReportValue = list.get(i);
            Object[] datas = new Object[7];
            datas[0] = idtReportValue.getIdtCode();
            datas[1] = idtReportValue.getIdtName();
            datas[2] = idtReportValue.getIdtUnit();
            datas[3] = idtReportValue.getDivisionName();
            datas[4] = idtReportValue.getDivisionCode();
            datas[5] = idtReportValue.getYear().toString();
            datas[6] = idtReportValue.getValue();
            dataList.add(datas);
        }
        // 导出Excel
        String[] titles = {"指标编号", "指标名称", "单位", "行政区划名称", "行政区划代码","年份", "上报值"};
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        response.setHeader("Content-type", "text/html;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        ExcelUtil.exportExcel(response, "评估指标", "评估指标信息", titles, dataList);
    }

    /**
     * @描述: 批量保存指标上报值
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2020/7/2 16:54
     **/
    @PostMapping("/savaMulReportValue")
    @ApiOperation(value = "批量保存指标上报值")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "formJson", value = "存放指标对象的json字符串", required = true, dataType = "string", paramType = "query")
    })
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult savaMulReportValue(String formJson){
        List<IdtReportValue> list = JSONObject.parseArray(formJson, IdtReportValue.class);
        List<IdtReportValue> addIdtTargetValueList = new ArrayList<>();
        List<IdtReportValue> updateIdtTargetValueList =  new ArrayList<>();
        if(null == list || list.size() == 0){
            return new AjaxResult(StatusCode.ERROR_CODE_40005,"参数格式错误，请检查");
        }
        for (IdtReportValue idtReportValue: list) {
            LambdaQueryWrapper<IdtReportValue> queryWrapper = new QueryWrapper().lambda();
            queryWrapper.eq(IdtReportValue::getIndicatorsId,idtReportValue.getIndicatorsId());
            queryWrapper.eq(IdtReportValue::getYear,idtReportValue.getYear());
            queryWrapper.eq(IdtReportValue::getDivisionCode,idtReportValue.getDivisionCode());
            List<IdtReportValue> IdtReportValues = idtReportValueService.list(queryWrapper);
            if(IdtReportValues.size() >0){
                IdtReportValue idtTargetValue1 = IdtReportValues.get(0);
                idtTargetValue1.setValue(idtReportValue.getValue());
                prepareData(idtTargetValue1,false);
                //判断是否统一
                Integer unify = idtReportValueService.isUnify(idtTargetValue1.getIndicatorsId(), idtTargetValue1.getYear() + "", idtTargetValue1.getDivisionCode(), idtTargetValue1.getValue());
                idtTargetValue1.setIsUnify(unify);
                //判断是否达标
                Integer standard = idtReportValueService.isStandard(idtTargetValue1.getIndicatorsId(), idtTargetValue1.getYear() + "", idtTargetValue1.getDivisionCode(), idtTargetValue1.getValue());
                idtTargetValue1.setIsStandard(standard);
                updateIdtTargetValueList.add(idtTargetValue1);
            }else {
                idtReportValue.setId(UuidUtil.get32UUID());
                prepareData(idtReportValue,true);
                //判断是否统一
                Integer unify = idtReportValueService.isUnify(idtReportValue.getIndicatorsId(), idtReportValue.getYear() + "", idtReportValue.getDivisionCode(), idtReportValue.getValue());
                idtReportValue.setIsUnify(unify);
                //判断是否达标
                Integer standard = idtReportValueService.isStandard(idtReportValue.getIndicatorsId(), idtReportValue.getYear() + "", idtReportValue.getDivisionCode(), idtReportValue.getValue());
                idtReportValue.setIsStandard(standard);
                addIdtTargetValueList.add(idtReportValue);
            }
        }
        if(addIdtTargetValueList.size() > 0){
            idtReportValueService.saveBatch(addIdtTargetValueList);
        }
        if(updateIdtTargetValueList.size() > 0){
            idtReportValueService.updateBatchById(updateIdtTargetValueList);
        }
        return new AjaxResult();
    }


    /**
     * @描述: 导出【体检评估-评估数值】word文档
     * @作者: 陈宏成
     * @日期: 2021-01-18
     **/
    @PostMapping("/exportStatusAssessment")
    @ApiOperation(value = " 导出【体检评估-评估数值】word文档")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "indicatorsTypeCode", value = "指标体系分类code", required = true, dataType = "string", paramType = "query",example="ghpg"),
            @ApiImplicitParam(name = "orgId", value = "组织ID", required = true, dataType = "string", paramType = "query",example = "65fc1451aa4640c795b971ae9199456c"),
            @ApiImplicitParam(name = "divisionCode", value = "行政区划码", required = true, dataType = "string", paramType = "query",example = "3201"),
            @ApiImplicitParam(name = "year", value = "年份", required = true, dataType = "string", paramType = "query",example = "2019"),
            @ApiImplicitParam(name = "reservedIds", value = "需要保留下载的指标的id列表, 多个通过逗号,分割, 不传表示下载全部", required = false, dataType = "string", paramType = "query", example = "baa9d7bc04424d7887b3ad17b7c60ebc,baa9d7bc04424d7887b3ad17b7c60ebc")
    })
    public void exportStatusAssessment(HttpServletResponse response, String indicatorsTypeCode, String orgId, String divisionCode, Integer year, String reservedIds) throws Exception {
        //获取根据编码获取体系类型
        IdtIndicatorsType one = iIdtIndicatorsTypeService.findByCode(indicatorsTypeCode, year+"", divisionCode);
        //获取父节点下的所有数据
        List<ApiIdtIndicatorsDir> dataList = iIdtIndicatorsDirService.listDirByCode(one.getId(), null,null);
        // 过滤掉不存在的指标
        dataList = dataList.stream().filter(dir->{
            if(dir.getType() == 2){
                IdtIndicators idtIndicator = iIdtIndicatorsService.getById(dir.getIndicatorsId());
                return idtIndicator != null;
            }
            return true;
        }).collect(Collectors.toList());

        // FIXME: 内存过滤, 数据量大有问题 : dataList 中 过滤掉不需要保持的数据
        if(StringUtils.isNotBlank(reservedIds)){
            // 用户选中的指标或者目录
            Set<String> reservedIdSet = new HashSet<>(Arrays.asList(reservedIds.split(",")));
            Set<ApiIdtIndicatorsDir> targetIndicatorSet = dataList.stream().filter(e -> reservedIdSet.contains(e.getId())).collect(Collectors.toSet());
            List<String> allIndicatorIds = dataList.stream().map(e -> e.getId()).collect(Collectors.toList());

            // 获取需要保存的数据
            Set<ApiIdtIndicatorsDir> reservedSet = new HashSet<>();
            for (ApiIdtIndicatorsDir apiIdtIndicatorsDir : targetIndicatorSet) {
                List<ApiIdtIndicatorsDir> parents = filterParent2List(dataList, apiIdtIndicatorsDir, new ArrayList<>());
                List<ApiIdtIndicatorsDir> childs = filterChild2List(dataList, apiIdtIndicatorsDir, new ArrayList<>());
                reservedSet.addAll(parents);
                reservedSet.add(apiIdtIndicatorsDir);
                reservedSet.addAll(childs);
            }
            dataList = new ArrayList<>(reservedSet);

            // 按照原来的datalist进行排序
            dataList.sort((e1, e2)->{
                int io1 = allIndicatorIds.indexOf(e1.getId());
                int io2 = allIndicatorIds.indexOf(e2.getId());
                if (io1 != -1) {
                    io1 = allIndicatorIds.size() - io1;
                }
                if (io2 != -1) {
                    io2 = allIndicatorIds.size() - io2;
                }
                return io2 - io1;
            });
        }
        // 排序
        dataList = SortUtil.sortList(dataList,one.getId(),1);
        // 查询上报值
        dataList.parallelStream().forEach((idtDir)->{
            if(idtDir.getType()==2){
                List<ApiIndicatorsVal> apiIndicatorsValList = new ArrayList<>();
                for(int i = 4; i >= 0; i--) {
                    ApiIndicatorsVal apiIndicatorsVal = new ApiIndicatorsVal();
                    apiIndicatorsVal.setValue(null);
                    apiIndicatorsVal.setMonitorValue(null);
                    apiIndicatorsVal.setBaseValue(null);
                    apiIndicatorsVal.setTargetValue(null);
                    apiIndicatorsVal.setYear(null);
                    //获取上报值
                    LambdaQueryWrapper<IdtReportValue> lambda1 = new QueryWrapper().lambda();
                    lambda1.eq(IdtReportValue::getIndicatorsId,idtDir.getIndicatorsId());
                    lambda1.eq(IdtReportValue::getYear,year - i);
                    lambda1.eq(IdtReportValue::getDivisionCode,divisionCode);
                    List<IdtReportValue> list1 = idtReportValueService.list(lambda1);
                    if(list1!=null && list1.size()>0){
                        IdtReportValue idtReportValue = list1.get(0);
                        // 获取上报值、上报年份、达标率、同一率和指标说明
                        apiIndicatorsVal.setValue(idtReportValue.getValue());
                        apiIndicatorsVal.setYear(idtReportValue.getYear()+"");
                        apiIndicatorsVal.setIsStandard(idtReportValue.getIsStandard());
                        apiIndicatorsVal.setIsUnify(idtReportValue.getIsUnify());
                        apiIndicatorsVal.setReportExplain(idtReportValue.getExplain());
                    }
                    // 指标对标关系
                    LambdaQueryWrapper<IdtYearRelevance> lambda2 = new QueryWrapper().lambda();
                    lambda2.eq(IdtYearRelevance::getIndicatorsId,idtDir.getIndicatorsId());
                    List<IdtYearRelevance> idtYearRelevances = iIdtYearRelevanceService.list(lambda2);
                    //查询所有规划值基期值
                    LambdaQueryWrapper<IdtTargetValue> lambda3 = new QueryWrapper().lambda();
                    lambda3.eq(IdtTargetValue::getIndicatorsId,idtDir.getIndicatorsId());
                    if(idtYearRelevances!=null && !idtYearRelevances.isEmpty()){
                        for (int j = 0; j <idtYearRelevances.size() ; j++) {
                            IdtYearRelevance idtYearRelevance = idtYearRelevances.get(j);
                            String monitorReportYear = idtYearRelevance.getMonitorReportYear();
                            String[] split = monitorReportYear.split("-");
                            if(split!=null && split.length==2){
                                int starYear = Integer.valueOf(split[0]);
                                int endYear = Integer.valueOf(split[1]);
                                int monitorYear = year - i;
                                if(monitorYear>=starYear && monitorYear<=endYear){
                                    //规划目标年
                                    Integer planTargetYear = idtYearRelevance.getPlanTargetYear();
                                    apiIndicatorsVal.setTargetYear(planTargetYear+"");
                                    // 获取对应的规划值
                                    LambdaQueryWrapper<IdtTargetValue> lambda4 = new QueryWrapper().lambda();
                                    lambda4.eq(IdtTargetValue::getIndicatorsId,idtDir.getIndicatorsId());
                                    lambda4.eq(IdtTargetValue::getTargetYear,planTargetYear);
                                    lambda4.eq(IdtTargetValue::getDivisionCode,divisionCode);
                                    List<IdtTargetValue> list3 = iIdtTargetValueService.list(lambda4);
                                    if(list3!=null && list3.size()>0){
                                        IdtTargetValue idtTargetValue = list3.get(0);
                                        apiIndicatorsVal.setTargetExplain(idtTargetValue.getExplain());
                                        apiIndicatorsVal.setTargetValue(idtTargetValue.getTargetValue()+"");
                                    }
                                }
                            }
                        }
                    }
                    apiIndicatorsValList.add(apiIndicatorsVal);
                    if(i == 0){
                        idtDir.setApiIndicatorsVal(apiIndicatorsValList.get(4));
                    }
                }
                idtDir.setApiIndicatorsValList(apiIndicatorsValList);
            }
        });
        String docxFileUrl = null;
        try{
            // word文档
            String docxName = this.exportStatusAssessmentWord(one, dataList, divisionCode, year);
            docxFileUrl = FileUtil.tempFilePath + docxName;
            // 文件名
            String divisionText = idtReportValueService.getNameByDivisionCode(divisionCode);
            String newExportFileName = divisionText+"国土空间规划现状评估报告（"+ String.valueOf(year) +"年）" ;
            // 导出
            InputStream inputStream = new FileInputStream(docxFileUrl);
            response.setContentType("application/octet-stream;charset=UTF-8;");
            response.setHeader("Content-Disposition", "attachment; filename=\"" +  new String(newExportFileName.getBytes(),"iso-8859-1") + ".docx"+ "\"");
            ServletOutputStream outputStream = response.getOutputStream();
            byte[] bytes = new byte[1024];
            int len = 0;
            while ((len = inputStream.read(bytes)) > 0){
                outputStream.write(bytes,0,len);
            }
            inputStream.close();
            outputStream.flush();
            outputStream.close();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(docxFileUrl != null){
                FileUtil.deleteFile(docxFileUrl);
            }
        }
    }


    @PostMapping("/getWarnStatu")
    @ApiOperation(value = "获取评估指标值的预警状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "indicatorsId", value = "指标id", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "year", value = "上报年份", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "行政区划编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "reportValue", value = "评估值", required = true, dataType = "string", paramType = "query")
    })
    public AjaxResult getWarnStatu(String indicatorsId, String year, String divisionCode, String reportValue){
        // 2021-12-30 陈宏成
        String warnStatus = this.idtReportValueService.getWarnStatus(indicatorsId, reportValue, year, divisionCode);
        return new AjaxResult(warnStatus);
    }

    /**
     * @描述: 从dataList中过滤出所有的target的子数据, 并填充到指定列表
     * @入参: dataList 所有的数据
     * @入参: target 目标
     * @入参: retList 填充并返回的列表, 传入非空
     * @出参:
     * @作者: 余家鑫
     * @日期: 2021/4/8 下午14:37
     */
    private List<ApiIdtIndicatorsDir> filterChild2List(List<ApiIdtIndicatorsDir> dataList, ApiIdtIndicatorsDir target, List<ApiIdtIndicatorsDir> retList) {
        String id = target.getId();
        for (ApiIdtIndicatorsDir apiIdtIndicatorsDir : dataList) {
            if(Objects.equals(apiIdtIndicatorsDir.getParentId(), id)){
                retList.add(apiIdtIndicatorsDir);
                retList = filterChild2List(dataList, apiIdtIndicatorsDir, retList);
            }
        }

        return retList;
    }

    /**
     * @描述: 从dataList中过滤出所有的target的父数据, 并填充到指定列表
     * @入参: dataList 所有的数据
     * @入参: target 目标
     * @入参: retList 填充并返回的列表, 传入非空
     * @出参:
     * @作者: 余家鑫
     * @日期: 2021/4/8 上午11:31
     */
    private List<ApiIdtIndicatorsDir> filterParent2List(List<ApiIdtIndicatorsDir> dataList, ApiIdtIndicatorsDir target, List<ApiIdtIndicatorsDir> retList) {
        String parentId = target.getParentId();
        for (ApiIdtIndicatorsDir apiIdtIndicatorsDir : dataList) {
            if(Objects.equals(apiIdtIndicatorsDir.getId(), parentId)){
                retList.add(apiIdtIndicatorsDir);
                retList = filterParent2List(dataList, apiIdtIndicatorsDir, retList);
                break;
            }
        }

        return retList;
    }

    /**
     * @描述: 导出【现状分析报告】到本地临时文件夹
     * @入参: indicatorsType 指标体系，非空必填
     * @入参: idtIndicatorsDirs 指标目录数据，非空必填
     * @入参: divisionCode 行政区划代码，非空必填
     * @入参: year 年份，非空必填
     * @出参: String 临时文档名
     * @作者: 陈宏成
     * @日期: 2021/01/18
     **/
    private String exportStatusAssessmentWord(IdtIndicatorsType indicatorsType, List<ApiIdtIndicatorsDir> idtIndicatorsDirs, String divisionCode, Integer year) throws Exception {
        // 行政区划
        String divisionText = idtReportValueService.getNameByDivisionCode(divisionCode);
        // 指标数量统计
        long idtIndicatorNum = idtIndicatorsDirs.stream().filter(x -> x.getType() == 2).count();
        // 已上报指标项
        Long reportedNum = idtIndicatorsDirs.stream().filter(idt->idt.getType() == 2 && StringUtils.isNotBlank(idt.getApiIndicatorsVal().getYear()) && idt.getApiIndicatorsVal().getYear().equals(String.valueOf(year))).count();
        // 未上报指标项
        Long unReportedNum = idtIndicatorsDirs.stream().filter(idt->idt.getType() == 2 && !StringUtils.isNotBlank(idt.getApiIndicatorsVal().getYear())).count();
        // 基本指标项
        long basicIdtIndicatorNum = idtIndicatorsDirs.stream().filter(x -> x.getType() == 2 && "basic".equals(x.getIdtType())).count();
        // 推荐指标项
        long recommendIdtIndicatorNum = idtIndicatorsDirs.stream().filter(x -> x.getType() == 2 && "recommend".equals(x.getIdtType())).count();
        // 地方指标项
        long placeIdtIndicatorNum = idtIndicatorsDirs.stream().filter(x -> x.getType() == 2 && "place".equals(x.getIdtType())).count();
        // 文档域字段
        List<Map<String, Object>> fieldData = new ArrayList<>(2);
        HashMap<String, Object> docFieldMap = new HashMap<>();
        HashMap<String, Object> docHtmlFieldMap = new HashMap<>();
        fieldData.add(docFieldMap);
        fieldData.add(docHtmlFieldMap);
        // 普通文档域字段
        ArrayList<Object> fieldList = new ArrayList<>();
        HashMap<String, Object> fieldMap = new HashMap<>();
        fieldMap.put("XZQ",divisionText == null? "":divisionText);
        fieldMap.put("NF",year);
        fieldMap.put("ZBX",idtIndicatorNum);
        fieldMap.put("JBZBX",basicIdtIndicatorNum);
        fieldMap.put("TJZBX",recommendIdtIndicatorNum);
        fieldMap.put("DFZBX",placeIdtIndicatorNum);
        fieldMap.put("YWCZBX",reportedNum);
        fieldMap.put("TBL", ConvertUtil.formatNumber((idtIndicatorNum == 0 ? 0.0 : (Double.valueOf(reportedNum) / Double.valueOf(idtIndicatorNum)) * 100.0), 2) + "%");
        fieldMap.put("Q4N",year-4);
        fieldMap.put("Q3N",year-3);
        fieldMap.put("Q2N",year-2);
        fieldMap.put("Q1N",year-1);
        fieldList.add(fieldMap);
        docFieldMap.put("table",fieldList);
        // 文档的html字段
        docHtmlFieldMap.put("type","html");
        List<Map<String, String>> htmlStrList = new ArrayList<>(1);
        docHtmlFieldMap.put("table",htmlStrList);
        HashMap<String, String> htmlStrMap = new HashMap<>(1);
        htmlStrList.add(htmlStrMap);
        // 文档表格字段
        List<Map<String, Object>> tableData = new ArrayList<>();
        HashMap<String, Object> tableDataMap = new HashMap<>();
        tableData.add(tableDataMap);
        tableDataMap.put("name","ZBMX");
        List<Map<String, Object>> tableDataList = new ArrayList<>();
        tableDataMap.put("table",tableDataList);
        // 抽取出指标项
        List<ApiIdtIndicatorsDir> idtIndicatorsList = idtIndicatorsDirs.stream().filter(idt -> idt.getType() == 2).collect(Collectors.toList());
        // 抽取出指标目录
        List<ApiIdtIndicatorsDir> idtIndicatorsDirList = idtIndicatorsDirs.stream().filter(idt -> idt.getType() == 1).collect(Collectors.toList());
        for(int i = 0; i < idtIndicatorsList.size(); i++) {
            ApiIdtIndicatorsDir apiIdtIndicator = idtIndicatorsList.get(i);
            Map<String, Object> rowDataMap = new HashMap<>();
            rowDataMap.put("XH",i+1);
            if(!StringUtils.isNotBlank(apiIdtIndicator.getIdtScope())){
                rowDataMap.put("FW","");
            }else if("all".equals(apiIdtIndicator.getIdtScope().trim())){
                rowDataMap.put("FW","全域");
            }else if("city".equals(apiIdtIndicator.getIdtScope().trim())){
                rowDataMap.put("FW","城区");
            }else {
                rowDataMap.put("FW","");
            }
            rowDataMap.put("Q4NSBZ",this.holdTwoDecimal(apiIdtIndicator.getApiIndicatorsValList().get(0).getValue()));
            rowDataMap.put("Q3NSBZ",this.holdTwoDecimal(apiIdtIndicator.getApiIndicatorsValList().get(1).getValue()));
            rowDataMap.put("Q2NSBZ",this.holdTwoDecimal(apiIdtIndicator.getApiIndicatorsValList().get(2).getValue()));
            rowDataMap.put("Q1NSBZ",this.holdTwoDecimal(apiIdtIndicator.getApiIndicatorsValList().get(3).getValue()));
            rowDataMap.put("DNSBZ",this.holdTwoDecimal(apiIdtIndicator.getApiIndicatorsVal().getValue()));
            rowDataMap.put("BZ",apiIdtIndicator.getApiIndicatorsVal().getReportExplain());
            // 寻找当前指标的上级目录
            String[] titleFields = {"YJML","EJML","SJML","ZBMC"};
            List<String> titleValues = new LinkedList<>();
            titleValues.add(apiIdtIndicator.getIdtName() == null ? "" : apiIdtIndicator.getIdtName() );
            StringBuilder parentId = new StringBuilder(apiIdtIndicator.getParentId());
            // 寻找上级目录
            while(true){
                ApiIdtIndicatorsDir parentDir = idtIndicatorsDirList.stream().filter(dir -> dir.getId().equals(parentId.toString())).findAny().orElse(null);
                if(parentDir == null){
                    break;
                }else{
                    titleValues.add(0,parentDir.getName());
                    parentId.delete(0,parentId.length());
                    parentId.append(parentDir.getParentId());
                }
            }
            // 将上级目录放入map
            for(int j = 0,titleValuesIndex = 0; j < titleFields.length; j++, titleValuesIndex++) {
                String titleField = titleFields[j];
                if(titleValuesIndex < titleValues.size()){
                    rowDataMap.put(titleField, titleValues.get(titleValuesIndex));
                }else{
                    rowDataMap.put(titleField, null);
                }
            }
            tableDataList.add(rowDataMap);
        }
        // 整理合并单元格数据
        List<Map<String, Object>> mergeTableList = new ArrayList<>(1);
        HashMap<String, Object> mergeTableMap = new HashMap<>(2);
        mergeTableList.add(mergeTableMap);
        mergeTableMap.put("xh",0);
        // 处理竖向单元格合并，一级目录，二级目录
        List<Map<String, String>> mergeTableCellList = this.buildMergeCells(new String[][]{{"YJML", "1"}, {"EJML", "2"}, {"SJML", "3"}, {"ZBMC", "4"}},  tableDataList, 1);
        mergeTableMap.put("cells",mergeTableCellList);
        // 构建第二部分的内容
        StringBuilder stringBuilder = new StringBuilder("");
        //创建树形结构
        idtIndicatorsDirs = createTree(indicatorsType.getId(), idtIndicatorsDirs);
        // 遍历
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("year",year);
        dataMap.put("tableNum",0);
        dataMap.put("level_num_1",0);
        for(ApiIdtIndicatorsDir idtIndicatorsDir : idtIndicatorsDirs) {
            dataMap.put("level",1);
            String htmlStr = this.buildStatusAssessmentWordHtmlStr(idtIndicatorsDir, dataMap);
            stringBuilder.append(htmlStr);
        }
        if(stringBuilder.length() > 0){
            stringBuilder.insert(0,"<h1 style=\"font-family:'宋体';font-size:18px;\">二、指标监测详情</h1>");
        }
        stringBuilder.insert(0,"<style>table,td,th{font-size:12px;border:1px solid grey;padding:5px;width:555px;text-align:center;}p,span,h1,h2,h3,div{font-family:'宋体';}*{font-family:'宋体';}</style>");
        htmlStrMap.put("html_str",stringBuilder.toString());
        // 加载模板文件
        ClassPathResource resource = new ClassPathResource("template/【现状评估】评估数值导出报告.docx");
        InputStream inputStream = resource.getInputStream();
        //进行word打印
        String docx = NewWordUtil.wordprint(inputStream, fieldData, tableData, null, "docx", "", "", mergeTableList);
        inputStream.close();
        return docx.substring(docx.lastIndexOf("/") + 1, docx.length());
    }
    /**
     * @描述: 构建合并单元格
     * @入参: mergeFields 合并单元格字段配置，{{"列字段名称","列字段下标，从0开始"},{"YJML", "1"}, {"EJML", "2"}, {"SJML", "3"}, {"ZBMC", "4"}}
     * @入参: tableDataList 数据列表
     * @入参: dataRowStartIndex 数据列开始行的下标
     * @出参: 合并单元格
     * @作者: 陈宏成
     * @日期: 2021/01/20
     **/
    private List<Map<String, String>> buildMergeCells(String[][] mergeFields, List<Map<String, Object>> tableDataList, int dataRowStartIndex){
        List<Map<String, String>> mergeTableCellList = new ArrayList<>();
        int rowStart = 0, rowEnd = 0, colStart = 0, colEnd = 0;
        // 每列纵向合并
        for(String[] mergeField : mergeFields) {
            rowStart = dataRowStartIndex;
            rowEnd = dataRowStartIndex;
            colStart = Integer.valueOf(mergeField[1]);
            colEnd = Integer.valueOf(mergeField[1]);
            // 遍历所有行
            String title = null;
            for(int i = 0; i < tableDataList.size(); i++) {
                Map<String, Object> dataMap = tableDataList.get(i);
                String tempTitle =  (String)dataMap.get(mergeField[0]);
                if(title == null){
                    // 如果是第一行，直接算相等
                    title = tempTitle;
                } else if (title.equals(tempTitle)){
                    rowEnd++;
                    // 如果是最后一条记录，直接添加一个合并单元格
                    if(i == tableDataList.size() - 1){
                        HashMap<String, String> cellsMap = new HashMap<>(1);
                        cellsMap.put("rowCell",rowStart + "," + colStart + "," + rowEnd + "," + colEnd);
                        mergeTableCellList.add(cellsMap);
                    }
                }else{
                    // 记录当前的文本内容
                    title = tempTitle;
                    // 添加一个合并单元格
                    HashMap<String, String> cellsMap = new HashMap<>(1);
                    cellsMap.put("rowCell",rowStart + "," + colStart + "," + rowEnd + "," + colEnd);
                    mergeTableCellList.add(cellsMap);
                    // 重置四个下标
                    rowStart = i + dataRowStartIndex;
                    rowEnd = rowStart;
                }
            }
        }
        // 横向合并，如果指标名称为空，则则与左边单元格进行合并
        for(int i = 0; i < tableDataList.size(); i++) {
            rowStart = dataRowStartIndex + i;
            rowEnd = rowStart;
            colStart = Integer.valueOf(mergeFields[mergeFields.length - 1][1]);
            colEnd = colStart;
            Map<String, Object> stringObjectMap = tableDataList.get(i);
            for(int j = mergeFields.length - 1; j >= 0; j--) {
                String tempTitle = (String)stringObjectMap.get(mergeFields[j][0]);
                if (tempTitle == null){
                    colStart--;
                }else{
                    break;
                }
            }
            HashMap<String, String> cellsMap = new HashMap<>(1);
            cellsMap.put("rowCell",rowStart + "," + colStart + "," + rowEnd + "," + colEnd);
            mergeTableCellList.add(cellsMap);
        }
        return mergeTableCellList;
    }
    /**
     * @描述: 构建【现状分析】的导出文档的第二部分内容
     * @入参: indicatorsDir 指标目录，非空必填
     * @入参: dataMap 数据map，用于构建html的层级结构
     * @出参: String html字符串
     * @作者: 陈宏成
     * @日期: 2021/01/18
     **/
    private String buildStatusAssessmentWordHtmlStr(ApiIdtIndicatorsDir indicatorsDir, Map<String,Object> dataMap){
        StringBuilder stringBuilder = new StringBuilder("");
        // 获取其子项
        List<ApiIdtIndicatorsDir> indicatorsDirChildren = indicatorsDir.getChildren();
        // 如果没有子项或者是指标，直接返回
        if(indicatorsDir.getType() == 2 || indicatorsDirChildren == null || indicatorsDirChildren.isEmpty()){
            return "";
        }
        // 递归层级
        Integer level = (Integer)dataMap.get("level");
        // 抽取子项中的指标
        List<ApiIdtIndicatorsDir> indicatorsList = indicatorsDirChildren.stream().filter(dir -> dir.getType() == 2).collect(Collectors.toList());
        // 对抽取出来的指标进行构建html
        if(indicatorsList != null && !indicatorsList.isEmpty()){
            // 统计不达标的指标数
            long unStandardNum = indicatorsList.stream().filter(idt -> {
                return idt.getApiIndicatorsVal() != null && idt.getApiIndicatorsVal().getIsStandard() != null && idt.getApiIndicatorsVal().getIsStandard() == 0;
            }).count();
            // 表格序号
            Integer tableNum = (Integer)dataMap.get("tableNum");
            dataMap.put("tableNum",tableNum + 1);
            // 获取年份
            Integer year = (Integer)dataMap.get("year");
            stringBuilder.append("<p style=\"font-family:'宋体';font-size:18px;text-indent:2em;\">").append(indicatorsDir.getName())
                    .append("共有").append(indicatorsList.size()).append("项指标，").append(year).append("年共有").append(unStandardNum)
                    .append("项指标评估结果为不达标，具体数据如下表：</p>")
                    .append("<p style=\"font-family:'宋体';text-align:center;\" >表：2-").append(tableNum+1).append(indicatorsDir.getName()).append("指标表</p>")
                    .append("<table style =\"border-collapse:collapse;border: solid 1px #000;font-family:'宋体';\">")
                    .append("<tr><td>序号</td><td>指标项</td><td>").append(year).append("年指标值</td><td>规划值</td><td>差值（规划值-指标值）</td><td>评估结果</td></tr>");
            for(int i = 0; i < indicatorsList.size(); i++) {
                ApiIdtIndicatorsDir idtIndicator = indicatorsList.get(i);
                stringBuilder.append("<tr>")
                        .append("<td>").append(i+1).append("</td>")
                        .append("<td>").append(idtIndicator.getIdtName()).append("</td>")
                        .append("<td>").append(this.holdTwoDecimal(idtIndicator.getApiIndicatorsVal().getValue())).append("</td>");
                if (StringUtils.isNotBlank(idtIndicator.getApiIndicatorsVal().getTargetValue())){
                    stringBuilder.append("<td>（").append(idtIndicator.getApiIndicatorsVal().getTargetYear()).append("年）").append(this.holdTwoDecimal(idtIndicator.getApiIndicatorsVal().getTargetValue())).append("</td>");
                }else{
                    stringBuilder.append("<td>").append("</td>");
                }

                if(idtIndicator.getApiIndicatorsVal().getValue() != null && idtIndicator.getApiIndicatorsVal().getTargetValue() != null){
                    stringBuilder.append("<td>").append(this.holdTwoDecimal(String.valueOf(Double.valueOf(idtIndicator.getApiIndicatorsVal().getTargetValue()) - Double.valueOf(idtIndicator.getApiIndicatorsVal().getValue())))).append("</td>");
                }else{
                    stringBuilder.append("<td></td>");
                }
                if (idtIndicator.getApiIndicatorsVal().getIsStandard() != null && idtIndicator.getApiIndicatorsVal().getIsStandard() == 1){
                    stringBuilder.append("<td>达标</td></tr>");
                }else if(idtIndicator.getApiIndicatorsVal().getIsStandard() != null && idtIndicator.getApiIndicatorsVal().getIsStandard() == 0){
                    stringBuilder.append("<td style=\"color:#ff4949\">不达标</td></tr>");
                }else{
                    stringBuilder.append("<td></td></tr>");
                }
            }
            stringBuilder.append("</table>");
        }
        // 抽取子项中的目录
        List<ApiIdtIndicatorsDir> indicatorsDirList = indicatorsDirChildren.stream().filter(dir -> dir.getType() == 1).collect(Collectors.toList());
        // 循环对抽取出的目录进行递归构建
        if(indicatorsDirList != null && !indicatorsDirList.isEmpty()){
            dataMap.put("level_num_"+(level+1),0);
            for(ApiIdtIndicatorsDir apiIdtIndicatorsDir : indicatorsDirList) {
                dataMap.put("level",level+1);
                String htmlStr = this.buildStatusAssessmentWordHtmlStr(apiIdtIndicatorsDir, dataMap);
                dataMap.put("level",level);
                stringBuilder.append(htmlStr);
            }
            dataMap.remove("level_num_" + (level + 1));
        }
        // 如果本轮中有html字符串返回，则添加本轮标题
        if (stringBuilder.length() > 0){
            Integer levelNum = (Integer)dataMap.get("level_num_" + level) + 1;
            dataMap.put("level_num_"+level,levelNum);
            String indexStr;
            if (level == 2){
                indexStr = "(" + levelNum + ").";
            }else{
                indexStr = levelNum + ".";
            }
            stringBuilder.insert(0,"<h"+(1+level)+" style=\"font-family:'宋体';font-size:18px;\">"+ indexStr + indicatorsDir.getName()+"</h" + (1+level) + ">");
        }
        return stringBuilder.toString();
    }
    /**
     * @描述:递归创建树
     * @入参:
     * @出参:
     * @作者: 郑文彬
     * @日期: 2020/4/20 17:30
     **/
    private static List createTree(String parentId, List<ApiIdtIndicatorsDir> menus){
        List tree = new ArrayList<>();
        for (int i = 0; i < menus.size(); i++) {
            ApiIdtIndicatorsDir idtDirectory = menus.get(i);
            if(idtDirectory.getParentId().equals(parentId)){
                tree.add(idtDirectory);
                List children = createTree(idtDirectory.getId(), menus);
                if(children!=null && !children.isEmpty()){
                    idtDirectory.setChildren(children);
                }
            }
        }
        return  tree;
    }
    /**
     * @描述: 保留两位小数
     * @入参: value 原字符串
     * @出参: 如果value为空，返回空字符串，否则保留两位小数
     * @作者: 陈宏成
     * @日期: 2021/01/18
     **/
    private String holdTwoDecimal(String value){
        if(!org.springframework.util.StringUtils.hasText(value)){
            return "";
        }
        return ConvertUtil.formatNumber(Double.valueOf(value), 2);
    }

    private void prepareData(IdtReportValue idtReportValue, boolean isSave) {
        if(isSave){
            idtReportValue.setCreator(this.getUser().getUserId().toString());
            idtReportValue.setCreateTime(new Date());
            //防止误修改
            idtReportValue.setModifier(null);
            idtReportValue.setModifyTime(null);
        }else{
            idtReportValue.setModifier(this.getUser().getUserId().toString());
            idtReportValue.setModifyTime(new Date());
            //防止误修改
            idtReportValue.setCreator(null);
            idtReportValue.setCreateTime(null);
        }
    }
}
